import std;

using namespace std;

class Foo {
public:
	Foo(unique_ptr<int> data)	 : data(move(data)) {}
	~Foo() { cout << "Foo::~Foo()" << endl; }

private:
	unique_ptr<int> data;
};

int* my_alloc(int size) {
	return new int[size];
}

void my_free(int* ptr) {
	cout << "my_free" << endl;
	delete[] ptr;
}

void close(FILE *filePtr) {
	cout << "close" << endl;
	fclose(filePtr);
}


int main() {
	// *************** unique_ptr ***************

	// part 1: unique_ptr and move semantics
	auto myIntSmartPtr{ make_unique<int>(42) };
	Foo foo{ move(myIntSmartPtr) };

	// part 2: hold c-style  arrays
	auto myArraySmartPtr{ make_unique<int[]>(3) };
	myArraySmartPtr[0] = 1;
	myArraySmartPtr[1] = 2;
	myArraySmartPtr[2] = 3;
	for (int i = 0; i < 3; ++i) {
		cout << myArraySmartPtr[i] << endl;
	}

	// part 3: custom deleter
	auto myCustomSmartPtr{ unique_ptr<int[], decltype(&my_free)>{ my_alloc(3), my_free }};

	// *************** shared_ptr ***************
	FILE *f {fopen("test.txt", "w")};
	shared_ptr<FILE> filePtr{ f, close };
	if (filePtr == nullptr) {
		cout << "Error opening file" << endl;
		return 1;
	}
	else {
		cout << "File opened successfully" << endl;
	}
}
